package com.jiedeng.controller.index;

import com.jiedeng.dao.ICorpPostRepository;
import com.jiedeng.dao.ICorpRepository;
import com.jiedeng.dao.IProjectRepository;
import com.jiedeng.mapper.ReportMapper;
import com.jiedeng.model.CheckCount;
import com.jiedeng.model.Corp;
import com.jiedeng.model.CorpPost;
import com.jiedeng.model.Project;
import com.jiedeng.util.DatetimeUtil;
import com.jiedeng.util.ExcelUtil;
import com.jiedeng.util.QiniuUtil;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.Region;
import org.apache.poi.util.StringUtil;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 详细报表
 *
 * @author zhouyb
 * 2018/4/13.
 */
@RestController
@Scope("prototype")
@RequestMapping("/detailedReport")
public class DetailedReportController {
    private final Logger log = LoggerFactory.getLogger(DetailedReportController.class);
    @Autowired
    ReportMapper reportMapper;
    @Autowired
    IProjectRepository projectRepository;
    @Autowired
    ICorpRepository corpRepository;
    @Autowired
    ICorpPostRepository corpPostRepository;

    @Value("${config.prefix}")
    private String prefix;
    @Value("${config.winReporterPath}")
    private String winPath;

    @Value("${config.linuxReporterPath}")
    private String linuxPath;
    @Value("${config.corpTempPath}")
    private String corpTempPath;
    @Value("${config.personTempPath}")
    private String personTempPath;

    /**
     * 获取格式list
     *
     * @param trendsViewMap
     * @return
     */
    public List<Map<String, Object>> getMapList(Map<String, List<Map<String, Object>>> trendsViewMap) {
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(10);
        for (String key : trendsViewMap.keySet()) {
            Map map = new HashMap();
            map.put("key", key);
            map.put("list", trendsViewMap.get(key));
            list.add(map);
        }
        return list;
    }

    /**
     * 明细表单位得分统计
     *
     * @param projectId
     * @return
     */
    @RequestMapping("detailedReport")
    public Map<String, List<?>> detailedReport(Long projectId) {
        List<Map<String, Object>> countList = reportMapper.detailedReport(projectId);
        Map<String, List<Map<String, Object>>> trendsViewMap = new HashMap<>();
        List<Integer> timeNumList = new ArrayList<>();
        Map<String, Integer> timeMap = new HashMap<>();
        int i = 1;
        for (Map<String, Object> map : countList) {
            if (!StringUtils.isEmpty(map.get("Start_Time"))) {
                if (timeMap.containsKey(map.get("Start_Time") + "")) {
                    map.put("timeNum", timeMap.get(map.get("Start_Time") + ""));
                } else {
                    timeMap.put(map.get("Start_Time") + "", i);
                    map.put("timeNum", i);
                    timeNumList.add(i);
                    i++;
                }
            }
            if (StringUtils.isEmpty(map.get("Scoring"))) {
                map.put("Scoring", map.get("Weighting"));
            }
//            if (!StringUtils.isEmpty(map.get("Scoring")) && !StringUtils.isEmpty(map.get("Weighting"))) {
            DecimalFormat decimalFormat = new DecimalFormat("0.00");
//                Double price = Double.valueOf(map.get("Scoring") + "") * 100.0 / Double.valueOf(map.get("Weighting") + "");
            Double price = getCorpScoring(map.get("Corp_Prop_ID"), projectId, map.get("Corp_ID"), map.get("Start_Time"));
            map.put("price", decimalFormat.format(price));
//            } else {
//                map.put("price", 0);
//            }

            if (trendsViewMap.containsKey(map.get("Corp_Caption") + "")) {
                List<Map<String, Object>> maplist = trendsViewMap.get(map.get("Corp_Caption") + "");
                maplist.add(map);
                trendsViewMap.put(map.get("Corp_Caption") + "", maplist);
            } else {
                List<Map<String, Object>> maplist = new ArrayList<Map<String, Object>>();
                maplist.add(map);
                trendsViewMap.put(map.get("Corp_Caption") + "", maplist);

            }
        }
        List<Map<String, Object>> list = getMapList(trendsViewMap);
        Map<String, List<?>> map = new HashMap<>(2);
        map.put("list", list);
        map.put("xList", timeNumList);
        return map;
    }

    /**
     * 获取单位得分
     *
     * @param corpPropId
     * @param projectId
     * @param corpId
     * @param startTime
     * @return
     */
    public Double getCorpScoring(Object corpPropId, Long projectId, Object corpId, Object startTime) {
        List<Map<String, Object>> list = reportMapper.getCorpScoringByProjectIdAndCorpIdAndTime(Long.valueOf(corpPropId + ""), projectId, Long.valueOf(corpId + ""), startTime + "");
        Double price = 0.0;
        if (list != null && list.size() > 0) {
            Double total = 0.0;
            for (Map<String, Object> corpScoringMap : list) {
                DecimalFormat decimalFormat = new DecimalFormat("0.00");
                total += Double.valueOf(decimalFormat.format(Double.valueOf(corpScoringMap.get("Scoring") + "") * 100 / Double.valueOf(corpScoringMap.get("Weighting") + "")));
            }
            price = total / list.size();
        }
        return price;
    }

    /**
     * 单位得分表 excel
     *
     * @param projectId
     * @return
     */
    @RequestMapping(value = "detailedReportExcel", produces = "text/html; charset=UTF-8")
    public String detailedReportExcel(Long projectId) {

        String path = "";

        String os = System.getProperty("os.name");
        if (os.toLowerCase().startsWith("win")) {
            path = winPath;
        } else {
            path = linuxPath;
        }
//        String keyName = "单位得分表 - 副本.xlsx";
        String keyName = "单位得分表" + DatetimeUtil.getDateyyyyMMddhhmmss() + ".xlsx";
        // String keyName ="zhenggaibihuandan"+ DatetimeUtil.getDateyyyyMMddhhmmss() + ".xlsx";
        String fileName = path + keyName;
        ExcelUtil.downloadSmallFile(corpTempPath, fileName);
        FileInputStream in = null;
        XSSFWorkbook wb = null;
        try {

            in = new FileInputStream(fileName);
            wb = new XSSFWorkbook(in);
            int sheetNo = 0;
            XSSFSheet sheet = wb.getSheetAt(sheetNo);
            Row row = sheet.getRow(2);
            Project project = projectRepository.findById(projectId).get();
            ExcelUtil.createCellNoBorder(wb, row, (short) 1, project.getCaption());

            List<Map<String, Object>> countList = reportMapper.detailedReport(projectId);
            Map<String, Map<String, Map<String, Object>>> trendsViewMap = new HashMap<>();
            Map<String, Object> corpMap = new HashMap<>(3);
            int i = 3;
            List<String> dateList = new ArrayList<>();
            for (Map<String, Object> countMap : countList) {
                if (StringUtils.isEmpty(countMap.get("Scoring"))) {
                    countMap.put("Scoring", countMap.get("Weighting"));
                }
                //            if (!StringUtils.isEmpty(map.get("Scoring")) && !StringUtils.isEmpty(map.get("Weighting"))) {
                DecimalFormat decimalFormat = new DecimalFormat("0.00");
//                Double price = Double.valueOf(map.get("Scoring") + "") * 100.0 / Double.valueOf(map.get("Weighting") + "");
                Double price = getCorpScoring(countMap.get("Corp_Prop_ID"), projectId, countMap.get("Corp_ID"), countMap.get("Start_Time"));
                countMap.put("price", decimalFormat.format(price));
//            } else {
//                map.put("price", 0);
//            }
              /*  if (!StringUtils.isEmpty(countMap.get("Scoring")) && !StringUtils.isEmpty(countMap.get("Weighting"))) {
                    DecimalFormat decimalFormat = new DecimalFormat("0.00");
                    Double price = Double.valueOf(countMap.get("Scoring") + "") * 100.0 / Double.valueOf(countMap.get("Weighting") + "");
                    countMap.put("price", decimalFormat.format(price));
                } else {
                    countMap.put("price", 0);
                }*/
                if (!StringUtils.isEmpty(countMap.get("Start_Time"))) {
                    if (trendsViewMap.containsKey(countMap.get("Start_Time") + "")) {
                        Map<String, Map<String, Object>> map = trendsViewMap.get(countMap.get("Start_Time") + "");
                        map.put(countMap.get("Corp_Caption") + "", countMap);
                        trendsViewMap.put(countMap.get("Start_Time") + "", map);
                    } else {
                        dateList.add(countMap.get("Start_Time") + "");
                        Map<String, Map<String, Object>> map = new HashMap<>(16);
                        map.put(countMap.get("Corp_Caption") + "", countMap);
                        trendsViewMap.put(countMap.get("Start_Time") + "", map);
                    }
                }
                if (!corpMap.containsKey(countMap.get("Corp_Caption") + "")) {
                    corpMap.put(countMap.get("Corp_Caption") + "", countMap.get("Corp_Prop_ID"));
                }


             /*   if (trendsViewMap.containsKey(countMap.get("Start_Time") + "")) {
                } else {
                    trendsViewMap.put(countMap.get("Start_Time") + "", countMap);
                    i++;
                    row = sheet.getRow(i);
                    if (row == null) {
                        row = sheet.createRow(i);
                    }
                    ExcelUtil.createCell(wb, row, (short) 10, countMap.get("Start_Time").toString(), XSSFCellStyle.ALIGN_CENTER, XSSFCellStyle.VERTICAL_CENTER);
                    ExcelUtil.createCell(wb, row, (short) 0, (i - 3 + ""), XSSFCellStyle.ALIGN_CENTER, XSSFCellStyle.VERTICAL_CENTER);
                }
                if (!corpMap.containsKey(countMap.get("Corp_Prop_ID") + "")) {
                    corpMap.put(countMap.get("Corp_Prop_ID") + "", countMap.get("Corp_Caption").toString());
                }*/

            /*    if ((Long) countMap.get("Corp_Prop_ID") == 2) {
                    ExcelUtil.createCell(wb, row, (short) 1, countMap.get("price").toString(), XSSFCellStyle.ALIGN_CENTER, XSSFCellStyle.VERTICAL_CENTER);
                }
                if ((Long) countMap.get("Corp_Prop_ID") == 4) {
                    ExcelUtil.createCell(wb, row, (short) 4, countMap.get("price").toString(), XSSFCellStyle.ALIGN_CENTER, XSSFCellStyle.VERTICAL_CENTER);
                }
                if ((Long) countMap.get("Corp_Prop_ID") == 5) {
                    ExcelUtil.createCell(wb, row, (short) 7, countMap.get("price").toString(), XSSFCellStyle.ALIGN_CENTER, XSSFCellStyle.VERTICAL_CENTER);
                }*/
            }
            row = sheet.getRow(3);
            if (row == null) {
                row = sheet.createRow(3);
            }
            ExcelUtil.createCellNoBorder(wb, row, (short) 0, "检查时间");
            int cellNum = 0;
            for (String date : dateList) {
                cellNum++;
                ExcelUtil.createCellNoBorder(wb, row, (short) cellNum, date);
            }
            int rowNum = 3;
            for (String corpNme : corpMap.keySet()) {
                rowNum++;

                row = sheet.getRow(rowNum);
                if (row == null) {
                    row = sheet.createRow(rowNum);
                }
                cellNum = 0;
                String newCorpName = corpNme;
                if ("2".equals(corpMap.get(corpNme))) {
                    newCorpName += "(业主)";
                }
                if ("4".equals(corpMap.get(corpNme))) {
                    newCorpName += "(监理)";
                }
                if ("5".equals(corpMap.get(corpNme))) {
                    newCorpName += "(施工)";
                }
                ExcelUtil.createCellNoBorder(wb, row, (short) cellNum, newCorpName);
                for (String date : dateList) {
                    cellNum++;
                    if (trendsViewMap.get(date) != null && trendsViewMap.get(date).get(corpNme) != null) {
                        String price = trendsViewMap.get(date).get(corpNme).get("price") + "";
                        ExcelUtil.createCellNoBorder(wb, row, (short) cellNum, price);
                    } else {
                        ExcelUtil.createCellNoBorder(wb, row, (short) cellNum, "");
                    }

                }
            }

//            ExcelUtil.createCell(wb, row, (short) 1, corpMap.get("2") + "(业主)", XSSFCellStyle.ALIGN_CENTER, XSSFCellStyle.VERTICAL_CENTER);
//            ExcelUtil.createCell(wb, row, (short) 4, corpMap.get("4") + "(监理)", XSSFCellStyle.ALIGN_CENTER, XSSFCellStyle.VERTICAL_CENTER);
//            ExcelUtil.createCell(wb, row, (short) 7, corpMap.get("5") + "(施工)", XSSFCellStyle.ALIGN_CENTER, XSSFCellStyle.VERTICAL_CENTER);
            FileOutputStream out = new FileOutputStream(fileName);
            wb.write(out);
            in.close();
            out.close();
            QiniuUtil qiniuUtil = new QiniuUtil();
            qiniuUtil.upload(fileName, keyName);
            return prefix + keyName;
        } catch (Exception e) {
//            System.out.println(e.toString());
            log.error("单位得分表出错", e);
            return "server error";
        } finally {
            try {
                in.close();
            } catch (Exception e) {
                log.error(e.toString());
            }
        }

    }

    /**
     * 明细表单位人员得分统计
     *
     * @param projectId
     * @return
     */
    @RequestMapping(value = "detailedCorpPersonReport")
    public Map<String, List<?>> detailedCorpPersonReport(Long projectId, Long corpId) {

        List<Map<String, Object>> countList = reportMapper.detailedCorpPersonReport(projectId, corpId);
        Map<String, Map<String, Map<String, Object>>> trendsViewMap = new HashMap<>();
        List<String> dateList = new ArrayList<>();
        List<Integer> timeNumList = new ArrayList<>();
        Map<String, Integer> timeMap = new HashMap<>();
        int i = 1;
        for (Map<String, Object> countMap : countList) {
            if (!StringUtils.isEmpty(countMap.get("Start_Time"))) {
                if (!timeMap.containsKey(countMap.get("Start_Time") + "")) {
                    timeMap.put(countMap.get("Start_Time") + "", i);
                    timeNumList.add(i);
                    i++;
                }
            }
            if (StringUtils.isEmpty(countMap.get("Scoring"))) {
                countMap.put("Scoring", countMap.get("Weighting"));
            }
            if (!StringUtils.isEmpty(countMap.get("Scoring")) && !StringUtils.isEmpty(countMap.get("Weighting"))) {
                DecimalFormat decimalFormat = new DecimalFormat("0.00");
                Double price = Double.valueOf(countMap.get("Scoring") + "") * 100.0 / Double.valueOf(countMap.get("Weighting") + "");
                countMap.put("price", decimalFormat.format(price));
            } else {
                countMap.put("price", 100);
            }
            if (!StringUtils.isEmpty(countMap.get("Start_Time"))) {
                if (trendsViewMap.containsKey(countMap.get("Start_Time") + "")) {
                    Map<String, Map<String, Object>> map = trendsViewMap.get(countMap.get("Start_Time") + "");
                    map.put(countMap.get("Post_Caption") + "", countMap);
                    trendsViewMap.put(countMap.get("Start_Time") + "", map);
                } else {
                    dateList.add(countMap.get("Start_Time") + "");
                    Map<String, Map<String, Object>> map = new HashMap<>(16);
                    map.put(countMap.get("Post_Caption") + "", countMap);
                    trendsViewMap.put(countMap.get("Start_Time") + "", map);
                }
            }
        }
        List<CorpPost> corpPostList = corpPostRepository.findCorpPostByCorpIdSQL(corpId, projectId);
//        List<Map<String, Object>> list = new ArrayList<>(10);
        Map<String, List<Map<String, Object>>> trendsViewListMap = new HashMap<>();
        for (CorpPost corpPost : corpPostList) {
            for (String date : dateList) {

                Map<String, Object> map = new HashMap<>(16);
                map.put("Corp_Caption", corpPost.getCaption());
                map.put("Start_Time", date);
                if (trendsViewMap.get(date) != null && trendsViewMap.get(date).get(corpPost.getCaption()) != null) {
                    String price = trendsViewMap.get(date).get(corpPost.getCaption()).get("price") + "";
                    map.put("price", price);
                } else {
                    map.put("price", "100");
                }
                map.put("timeNum", timeMap.get(date));
                if (trendsViewListMap.containsKey(map.get("Corp_Caption") + "")) {
                    List<Map<String, Object>> maplist = trendsViewListMap.get(map.get("Corp_Caption") + "");
                    maplist.add(map);
                    trendsViewListMap.put(map.get("Corp_Caption") + "", maplist);
                } else {
                    List<Map<String, Object>> maplist = new ArrayList<Map<String, Object>>();
                    maplist.add(map);
                    trendsViewListMap.put(map.get("Corp_Caption") + "", maplist);
                }

            }
        }
        List<Map<String, Object>> list = getMapList(trendsViewListMap);
        Map<String, List<?>> map = new HashMap<>(2);
        map.put("list", list);
        map.put("xList", timeNumList);
        return map;
    }


    /**
     * 人员得分表 excel
     *
     * @param projectId
     * @param corpId
     * @return
     */
    @RequestMapping(value = "detailedCorpPersonReportExcel", produces = "text/html; charset=UTF-8")
    public String detailedCorpPersonReportExcel(Long projectId, Long corpId) {

        String path = "";

        String os = System.getProperty("os.name");
        if (os.toLowerCase().startsWith("win")) {
            path = winPath;
        } else {
            path = linuxPath;
        }
//        String keyName = "人员得分表 - 副本.xlsx";
        String keyName = "人员得分表" + DatetimeUtil.getDateyyyyMMddhhmmss() + ".xlsx";
        // String keyName ="zhenggaibihuandan"+ DatetimeUtil.getDateyyyyMMddhhmmss() + ".xlsx";
        String fileName = path + keyName;
        ExcelUtil.downloadSmallFile(personTempPath, fileName);
        FileInputStream in = null;
        XSSFWorkbook wb = null;
        try {

            in = new FileInputStream(fileName);
            wb = new XSSFWorkbook(in);
            int sheetNo = 0;
            XSSFSheet sheet = wb.getSheetAt(sheetNo);
            Row row = sheet.getRow(2);
            Project project = projectRepository.findById(projectId).get();
            ExcelUtil.createCellNoBorder(wb, row, (short) 1, project.getCaption());
            Corp corp = corpRepository.findAllById(corpId);
            ExcelUtil.createCellNoBorder(wb, row, (short) 5, corp.getCaption());
            List<CorpPost> corpPostList = corpPostRepository.findCorpPostByCorpIdSQL(corpId, projectId);
//            corpPostMap.put("检查日期", cellNum);
//            ExcelUtil.createCell(wb, row, (short) cellNum, "检查日期", XSSFCellStyle.ALIGN_CENTER, XSSFCellStyle.VERTICAL_CENTER);
            List<Map<String, Object>> countList = reportMapper.detailedCorpPersonReport(projectId, corpId);
            Map<String, Map<String, Map<String, Object>>> trendsViewMap = new HashMap<>();
            List<String> dateList = new ArrayList<>();
            for (Map<String, Object> countMap : countList) {
                if (StringUtils.isEmpty(countMap.get("Scoring"))) {
                    countMap.put("Scoring", countMap.get("Weighting"));
                }
                if (!StringUtils.isEmpty(countMap.get("Scoring")) && !StringUtils.isEmpty(countMap.get("Weighting"))) {
                    DecimalFormat decimalFormat = new DecimalFormat("0.00");
                    Double price = Double.valueOf(countMap.get("Scoring") + "") * 100.0 / Double.valueOf(countMap.get("Weighting") + "");
                    countMap.put("price", decimalFormat.format(price));
                } else {
                    countMap.put("price", 100);
                }
                if (!StringUtils.isEmpty(countMap.get("Start_Time"))) {
                    if (trendsViewMap.containsKey(countMap.get("Start_Time") + "")) {
                        Map<String, Map<String, Object>> map = trendsViewMap.get(countMap.get("Start_Time") + "");
                        map.put(countMap.get("Post_Caption") + "", countMap);
                        trendsViewMap.put(countMap.get("Start_Time") + "", map);
                    } else {
                        dateList.add(countMap.get("Start_Time") + "");
                        Map<String, Map<String, Object>> map = new HashMap<>(16);
                        map.put(countMap.get("Post_Caption") + "", countMap);
                        trendsViewMap.put(countMap.get("Start_Time") + "", map);
                    }
                }
            }
            row = sheet.getRow(3);
            if (row == null) {
                row = sheet.createRow(3);
            }
            ExcelUtil.createCellNoBorder(wb, row, (short) 0, "检查时间");
            int cellNum = 0;
            for (String date : dateList) {
                cellNum++;
                ExcelUtil.createCellNoBorder(wb, row, (short) cellNum, date);
            }
            int rowNum = 3;
            for (CorpPost corpPost : corpPostList) {
                rowNum++;

                row = sheet.getRow(rowNum);
                if (row == null) {
                    row = sheet.createRow(rowNum);
                }
                cellNum = 0;
                ExcelUtil.createCellNoBorder(wb, row, (short) cellNum, corpPost.getCaption());
                for (String date : dateList) {
                    cellNum++;
                    if (trendsViewMap.get(date) != null && trendsViewMap.get(date).get(corpPost.getCaption()) != null) {
                        String price = trendsViewMap.get(date).get(corpPost.getCaption()).get("price") + "";
                        ExcelUtil.createCellNoBorder(wb, row, (short) cellNum, price);
                    } else {
                        ExcelUtil.createCellNoBorder(wb, row, (short) cellNum, "100");
                    }

                }
            }
            FileOutputStream out = new FileOutputStream(fileName);
            wb.write(out);
            in.close();
            out.close();
            QiniuUtil qiniuUtil = new QiniuUtil();
            qiniuUtil.upload(fileName, keyName);
            return prefix + keyName;
        } catch (Exception e) {
//            System.out.println(e.toString());
            log.error("人员得分表出错", e);
            return "server error";
        } finally {
            try {
                in.close();
            } catch (Exception e) {
                log.error(e.toString());
            }
        }

    }

    /**
     * 上传模板 excel
     *
     * @return
     */
    @RequestMapping("reportTempExcel")
    public String reportTempExcel(String keyName) {

        String path = "";

        String os = System.getProperty("os.name");
        if (os.toLowerCase().startsWith("win")) {
            path = winPath;
        } else {
            path = linuxPath;
        }
//        String keyName = "CORP-002.xlsx";
//        String keyName = "人员得分表" + DatetimeUtil.getDateyyyyMMddhhmmss() + ".xlsx";
        // String keyName ="zhenggaibihuandan"+ DatetimeUtil.getDateyyyyMMddhhmmss() + ".xlsx";
        String fileName = path + keyName;
//        ExcelUtil. downloadSmallFile(statisticsReportPath, fileName);
        FileInputStream in = null;
        XSSFWorkbook wb = null;
        try {
            in = new FileInputStream(fileName);
            wb = new XSSFWorkbook(in);
            FileOutputStream out = new FileOutputStream(fileName);
            wb.write(out);
            in.close();
            out.close();
            QiniuUtil qiniuUtil = new QiniuUtil();
            qiniuUtil.upload(fileName, keyName);
            return prefix + keyName;
        } catch (Exception e) {
//            System.out.println(e.toString());
            log.error("人员得分表出错", e);
            return "server error";
        } finally {
            try {
                in.close();
            } catch (Exception e) {
                log.error(e.toString());
            }
        }

    }

}
